package main

//go 协程学习
//2022年06月04日
//pdudo
//文件备份拷贝

import (
	"archive/tar"
	"io"
	"io/fs"
	"io/ioutil"
	"log"
	"os"
	"sync"
)

func main() {

	var wg sync.WaitGroup

	// 拷贝./etc/目录下的所有文件至 bak

	// 创建bak目录
	os.Mkdir("bak",os.ModePerm)

	filesInfo , err := ioutil.ReadDir("etc")
	if err != nil {
		panic(err)
	}

	for _,fileinfo := range filesInfo {
		if ! fileinfo.IsDir() {
			wg.Add(1)
			go func(fileinfo fs.FileInfo) {
				defer wg.Done()

				log.Println("dealwith filename " , fileinfo.Name())

				sourceFile , err := os.Open("etc/"+fileinfo.Name())
				if err != nil {
					log.Println("open " , fileinfo.Name() , " error" , err)
				}
				defer sourceFile.Close()

				destFile , err := os.OpenFile("bak/"+fileinfo.Name(),os.O_CREATE|os.O_WRONLY,fileinfo.Mode())
				if err != nil {
					log.Println("create file " , fileinfo.Name() , "error " , err)
				}
				defer destFile.Close()

				io.Copy(destFile,sourceFile)
			}(fileinfo)
		}
	}

	wg.Wait()

	compress()
}

func compress() {
	// 创建压缩目录
	tarFile , err := os.Create("bak.tar")
	if err != nil {
		log.Panic(err)
	}
	defer tarFile.Close()

	tw := tar.NewWriter(tarFile)
	defer tw.Close()

	filesInfo , err := ioutil.ReadDir("bak")
	if err != nil {
		panic(err)
	}

	for _,fileinfo := range filesInfo {
		if ! fileinfo.IsDir() {
			
			fileStatus,err := os.Stat("bak/" + fileinfo.Name())
			if err != nil {
				log.Println(err)
				return
			}

			tarHeader , err := tar.FileInfoHeader(fileStatus,"")
			if err != nil {
				log.Println(err)
				return
			}

			tw.WriteHeader(tarHeader)

			compressFile,err := os.Open("bak/"+fileinfo.Name())
			if err != nil {
				log.Println(err)
				return
			}
			defer compressFile.Close()

			io.Copy(tw,compressFile)

		}
	}
}